// import { BenchmarkRunner } from "../../../utils/benchmarkTsSuite";
declare function print(arg:any) : string;

declare interface ArkTools{
	timeInUs(arg:any):number
}

let global_value = 0;
/***** Without parameters *****/

/***************** With parameters *****************/
function Foo(a:number, b:number, c:number) {
    global_value += 1
}
function CallFoo(f:(n1: number, n2: number, n3: number) => void,a:number,b:number,c:number){
    f(a,b,c)
}
export function RunFunctionPtr():number {
    let count : number = 10000000;
    global_value = 0;
    let startTime = ArkTools.timeInUs();
    for(let i=0;i<count;i++){
        CallFoo(Foo,1,2,i);
    }
    let endTime = ArkTools.timeInUs();
    let time = (endTime - startTime) / 1000
    print("Function Call - RunFunctionPtr:\t"+String(time)+"\tms");
    return time
}
RunFunctionPtr()

/***************** No parameters *****************/
function ParameterlessFoo(){
    global_value += 1
}
function CallParameterlessFoo(f:() => void){
    f()
}
export function RunParameterlessFunctionPtr():number {
    let count : number = 10000000;
    global_value = 0;
    let startTime = ArkTools.timeInUs();
    for(let i=0;i<count;i++){
        CallParameterlessFoo(ParameterlessFoo);
    }
    let endTime = ArkTools.timeInUs();
    let time = (endTime - startTime) / 1000
    print("Function Call - RunParameterlessFunctionPtr:\t"+String(time)+"\tms");
    return time
}
RunParameterlessFunctionPtr()

/***************************** Default  parameters *****************************/
function DefaultFoo(a:number=0, b:string="b", c:boolean=true) {
    global_value += 1
}
function CallDefaultFoo(f:Function,a:number=0, b:string="b", c:boolean=true){
    f()
}
export function RunDefaultfunctionPtr():number {
    let count : number = 10000000;
    global_value = 0;
    let startTime = ArkTools.timeInUs();
    for(let i=0;i<count;i++){
        CallDefaultFoo(DefaultFoo);
    }
    let endTime = ArkTools.timeInUs();
    let time = (endTime - startTime) / 1000
    print("Function Call - RunDefaultfunctionPtr:\t"+String(time)+"\tms");
    return time
}
RunDefaultfunctionPtr()

/********************* Different  parameters *********************/
function DifferentFoo(a:number, b:string, c:boolean) {
    global_value += 1
}
function CallDifferentFoo(f:Function,a:number, b:string, c:boolean){
    f(a,b,c)
}
export function RunDifferentFunctionPtr():number {
    let count : number = 10000000;
    global_value = 0;
    let startTime = ArkTools.timeInUs();
    for(let i=0;i<count;i++){
        CallDifferentFoo(DifferentFoo,1,"1",true);
    }
    let endTime = ArkTools.timeInUs();
    let time = (endTime - startTime) / 1000
    print("Function Call - RunDifferentFunctionPtr:\t"+String(time)+"\tms");
    return time
}
RunDifferentFunctionPtr()

/************************* Variable  parameters *************************/
function VariableFoo(a?:number, b?:string, c?:boolean) {
    global_value += 1
}
function CallVariableFoo(f:Function,a?:number, b?:string, c?:boolean){
    f(a,b,c)
}
export function RunVariableFunctionPtr():number {
    let count : number = 10000000;
    global_value = 0;
    let startTime = ArkTools.timeInUs();
    for(let i=0;i<count;i++){
        CallVariableFoo(VariableFoo,1,"1",true);
    }
    let endTime = ArkTools.timeInUs();
    let time = (endTime - startTime) / 1000
    print("Function Call - RunVariableFunctionPtr:\t"+String(time)+"\tms");
    return time
}
RunVariableFunctionPtr()

print("Ts Method Call Is End, global_value value: \t" + String(global_value));

